﻿using System;
using System.Reflection;
using System.Runtime.InteropServices;


namespace WinAPI
{
    class FilePropertiesManager
    {
        const int MASK_INVOKEIDLIST = 0x00000C;
        const int MASK_NOCLOSEPROCESS = 0x000040;
        const int MASK_FLAG_NO_UI = 0x000400;

        [StructLayout(LayoutKind.Sequential)]
        private struct SHELLEXECUTEINFO
        {
            internal int Size;
            internal uint fMask;
            internal IntPtr hwnd;
            [MarshalAs(UnmanagedType.LPWStr)]
            internal string lpVerb;
            [MarshalAs(UnmanagedType.LPWStr)]
            internal string lpFile;
            [MarshalAs(UnmanagedType.LPWStr)]
            internal string lpParameters;
            [MarshalAs(UnmanagedType.LPWStr)]
            internal string lpDirectory;
            internal int nShow;
            internal IntPtr hInstApp;
            internal IntPtr lpIDList;
            [MarshalAs(UnmanagedType.LPWStr)]
            internal string lpClass;
            internal IntPtr hkeyClass;
            internal uint dwHotKey;
            internal IntPtr hIcon;
            internal IntPtr hProcess;
        }

        public static void ShowFilePropertyDlg( string filePath)
        {
            SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
            info.Size = Marshal.SizeOf(info);
            info.hwnd = IntPtr.Zero;
            info.fMask = (MASK_INVOKEIDLIST | MASK_NOCLOSEPROCESS | MASK_FLAG_NO_UI);

            //Properties dialog
            //for file or folder
            //to be displayed
            info.lpVerb = "properties";
            //using file of currently running assembly 
            //as an example
            info.lpFile = filePath;                
            if (!ShellExecuteEx(ref info))
            {
                int lastError = Marshal.GetLastWin32Error();
                throw new MarshalException();
            }
        }

        [DllImport("shell32.dll", SetLastError = true,EntryPoint = "ShellExecuteExW",CharSet = CharSet.Unicode)]
        private static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
    }
}

